package com.jnxx.task.taskRemind;

import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class MessageDelyQueueService {

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 延迟队列名称，可以根据不通的业务处理设置不同的队列
     */
    private static final String DELY_QUEUE_NAME = "dely_queue";

    /**
     * 锁key
     */
    public static final String LOCK_KEY = "message_lock_key";

    /**
     * 推送未接收任务消息
     * @param taskId 消息
     * @param dely    延迟多久（秒）
     */
    public Boolean pushMessage(Long taskId, int dely) {
        long score = System.currentTimeMillis() + (dely * 1000);
        String msg = JSONObject.toJSONString(taskId);
        Boolean add = redisTemplate.opsForZSet().add(DELY_QUEUE_NAME, msg, score);
        log.info("pushMessage加入延迟队列中的值：{}，分数值：{}，当前分数值：{}", taskId, score, System.currentTimeMillis());
        return add;
    }

    /**
     * 拉取最新需要
     * 被消费的消息
     * rangeByScore 根据score范围获取 0-当前时间戳可以拉取当前时间及以前的需要被消费的消息
     *
     * @return
     */
    public List<Long> pull() {

//        List<Task> msgList = new ArrayList<>();
        List<Long> staffIds = new ArrayList<>();
        try {

            Set<String> strings = redisTemplate.opsForZSet().rangeByScore(DELY_QUEUE_NAME, 0, System.currentTimeMillis());
            log.info("拉取值时，当前分数值：{}", System.currentTimeMillis());
            if (strings == null) {
                return null;
            }

            for (String str : strings) {
                try {
                    Long longValue = Long.parseLong(str);
                    staffIds.add(longValue);
                } catch (NumberFormatException e) {
                    // 处理转换失败的情况，例如字符串不是合法的长整型
                    System.out.println("Failed to convert: " + str);
                }
            }
//            msgList = strings.stream().map(msg -> {
//                Task task = null;
//                try {
//                    task = JSONObject.parseObject(msg, Task.class);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//                return task;
//            }).collect(Collectors.toList());
        } catch (Exception e) {
            log.error(e.toString());
        }
        return staffIds;
    }

    /**
     * 移除消息
     *
     * @param taskId
     */
    @SneakyThrows
    public Boolean remove(Long taskId) {
        Long remove = redisTemplate.opsForZSet().remove(DELY_QUEUE_NAME, JSONObject.toJSONString(taskId));
        log.info("remove删除延迟队列中的值：{}，删除状态：{}", taskId, remove);
        return remove > 0 ? true : false;
    }

    /**
     * 获取锁，这是使用的锁的方式比较简单 ，reids
     * 实现分布式锁比较复杂，这里不介绍
     *
     * @return
     */
    public Boolean getLock() {
        boolean lock = false;
        //获得锁
        lock = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY, DELY_QUEUE_NAME + "is locking !", 30, TimeUnit.SECONDS);
        return lock;
    }

    /**
     * 释放锁
     */
    public void releaseLock() {
        redisTemplate.delete(LOCK_KEY);
    }
}
